package com.zenithmind.document.controller;

import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.result.Result;
import com.zenithmind.document.pojo.vo.DocumentVO;
import com.zenithmind.document.service.DocumentSearchService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import java.util.List;

/**
 * 文档搜索控制器
 * 遵循单一职责原则：专注于文档搜索功能
 * 遵循依赖倒置原则：依赖抽象服务接口
 * 遵循接口隔离原则：只提供搜索相关功能
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@RestController
@RequestMapping("/api/document/search")
@RequiredArgsConstructor
@Validated
@Tag(name = "文档搜索", description = "文档搜索相关接口")
public class DocumentSearchController {

    private final DocumentSearchService documentSearchService;

    @GetMapping("/simple")
    @Operation(summary = "简单搜索", description = "根据关键词搜索文档")
    public Result<List<DocumentVO>> searchDocuments(
            @Parameter(description = "搜索关键词", required = true) @RequestParam @NotBlank String keyword,
            @Parameter(description = "限制数量") @RequestParam(required = false, defaultValue = "20") Integer limit) {
        
        log.info("简单搜索文档请求: keyword={}", keyword);
        
        String userId = UserContext.getUserId();
        List<DocumentVO> result = documentSearchService.searchDocuments(keyword, userId, limit);
        
        return Result.success(result);
    }

    @GetMapping("/advanced")
    @Operation(summary = "高级搜索", description = "根据多个条件搜索文档")
    public Result<List<DocumentVO>> advancedSearchDocuments(
            @Parameter(description = "搜索关键词") @RequestParam(required = false) String keyword,
            @Parameter(description = "分类ID") @RequestParam(required = false) String categoryId,
            @Parameter(description = "文档类型") @RequestParam(required = false) String type,
            @Parameter(description = "限制数量") @RequestParam(required = false, defaultValue = "20") Integer limit) {
        
        log.info("高级搜索文档请求: keyword={}, categoryId={}, type={}", keyword, categoryId, type);
        
        String userId = UserContext.getUserId();
        List<DocumentVO> result = documentSearchService.advancedSearchDocuments(keyword, categoryId, type, userId, limit);
        
        return Result.success(result);
    }

    @PostMapping("/by-tags")
    @Operation(summary = "按标签搜索", description = "根据标签列表搜索文档")
    public Result<List<DocumentVO>> searchDocumentsByTags(
            @Parameter(description = "标签列表", required = true) @RequestBody @NotEmpty List<String> tags,
            @Parameter(description = "限制数量") @RequestParam(required = false, defaultValue = "20") Integer limit) {
        
        log.info("按标签搜索文档请求: tags={}", tags);
        
        String userId = UserContext.getUserId();
        List<DocumentVO> result = documentSearchService.searchDocumentsByTags(tags, userId, limit);
        
        return Result.success(result);
    }

    @GetMapping("/related/{documentId}")
    @Operation(summary = "获取相关文档", description = "获取与指定文档相关的文档列表")
    public Result<List<DocumentVO>> getRelatedDocuments(
            @Parameter(description = "文档ID", required = true) @PathVariable @NotBlank String documentId,
            @Parameter(description = "限制数量") @RequestParam(required = false, defaultValue = "10") Integer limit) {
        
        log.info("获取相关文档请求: documentId={}", documentId);
        
        String userId = UserContext.getUserId();
        List<DocumentVO> result = documentSearchService.getRelatedDocuments(documentId, userId, limit);
        
        return Result.success(result);
    }

    @GetMapping("/recommended")
    @Operation(summary = "获取推荐文档", description = "获取为当前用户推荐的文档列表")
    public Result<List<DocumentVO>> getRecommendedDocuments(
            @Parameter(description = "限制数量") @RequestParam(required = false, defaultValue = "10") Integer limit) {
        
        log.info("获取推荐文档请求");
        
        String userId = UserContext.getUserId();
        List<DocumentVO> result = documentSearchService.getRecommendedDocuments(userId, limit);
        
        return Result.success(result);
    }

    @GetMapping("/hot")
    @Operation(summary = "获取热门文档", description = "获取热门文档列表")
    public Result<List<DocumentVO>> getHotDocuments(
            @Parameter(description = "限制数量") @RequestParam(required = false, defaultValue = "10") Integer limit) {
        
        log.info("获取热门文档请求");
        
        List<DocumentVO> result = documentSearchService.getHotDocuments(limit);
        
        return Result.success(result);
    }

    @GetMapping("/latest")
    @Operation(summary = "获取最新文档", description = "获取最新发布的文档列表")
    public Result<List<DocumentVO>> getLatestDocuments(
            @Parameter(description = "限制数量") @RequestParam(required = false, defaultValue = "10") Integer limit) {
        
        log.info("获取最新文档请求");
        
        String userId = UserContext.getUserId();
        List<DocumentVO> result = documentSearchService.getLatestDocuments(userId, limit);
        
        return Result.success(result);
    }

    @GetMapping("/favorites")
    @Operation(summary = "获取收藏文档", description = "获取当前用户收藏的文档列表")
    public Result<List<DocumentVO>> getFavoriteDocuments(
            @Parameter(description = "限制数量") @RequestParam(required = false, defaultValue = "20") Integer limit) {
        
        log.info("获取收藏文档请求");
        
        String userId = UserContext.getUserId();
        List<DocumentVO> result = documentSearchService.getFavoriteDocuments(userId, limit);
        
        return Result.success(result);
    }

    @GetMapping("/recent")
    @Operation(summary = "获取最近访问文档", description = "获取当前用户最近访问的文档列表")
    public Result<List<DocumentVO>> getRecentDocuments(
            @Parameter(description = "限制数量") @RequestParam(required = false, defaultValue = "10") Integer limit) {
        
        log.info("获取最近访问文档请求");
        
        String userId = UserContext.getUserId();
        List<DocumentVO> result = documentSearchService.getRecentDocuments(userId, limit);
        
        return Result.success(result);
    }

    @GetMapping("/user/{creatorId}")
    @Operation(summary = "获取用户文档", description = "获取指定用户创建的文档列表")
    public Result<List<DocumentVO>> getUserDocuments(
            @Parameter(description = "创建者ID", required = true) @PathVariable @NotBlank String creatorId,
            @Parameter(description = "限制数量") @RequestParam(required = false, defaultValue = "20") Integer limit) {
        
        log.info("获取用户文档请求: creatorId={}", creatorId);
        
        List<DocumentVO> result = documentSearchService.getUserDocuments(creatorId, limit);
        
        return Result.success(result);
    }

    @GetMapping("/category/{categoryId}")
    @Operation(summary = "按分类获取文档", description = "获取指定分类下的文档列表")
    public Result<List<DocumentVO>> getDocumentsByCategory(
            @Parameter(description = "分类ID", required = true) @PathVariable @NotBlank String categoryId,
            @Parameter(description = "限制数量") @RequestParam(required = false, defaultValue = "20") Integer limit) {
        
        log.info("按分类获取文档请求: categoryId={}", categoryId);
        
        String userId = UserContext.getUserId();
        List<DocumentVO> result = documentSearchService.getDocumentsByCategory(categoryId, userId, limit);
        
        return Result.success(result);
    }

    @GetMapping("/my")
    @Operation(summary = "获取我的文档", description = "获取当前用户创建的文档列表")
    public Result<List<DocumentVO>> getMyDocuments(
            @Parameter(description = "限制数量") @RequestParam(required = false, defaultValue = "20") Integer limit) {
        
        log.info("获取我的文档请求");
        
        String userId = UserContext.getUserId();
        List<DocumentVO> result = documentSearchService.getUserDocuments(userId, limit);
        
        return Result.success(result);
    }

    @GetMapping("/suggestions")
    @Operation(summary = "获取搜索建议", description = "根据输入获取搜索建议")
    public Result<List<String>> getSearchSuggestions(
            @Parameter(description = "输入关键词", required = true) @RequestParam @NotBlank String input,
            @Parameter(description = "限制数量") @RequestParam(required = false, defaultValue = "10") Integer limit) {
        
        log.info("获取搜索建议请求: input={}", input);

        try {
            String userId = UserContext.getUserId();

            // 实现搜索建议逻辑
            List<String> result = generateSearchSuggestions(input, userId, limit);

            return Result.success(result);
        } catch (Exception e) {
            log.error("获取搜索建议失败: input={}", input, e);
            return Result.fail("获取搜索建议失败: " + e.getMessage());
        }
    }

    @GetMapping("/history")
    @Operation(summary = "获取搜索历史", description = "获取当前用户的搜索历史")
    public Result<List<String>> getSearchHistory(
            @Parameter(description = "限制数量") @RequestParam(required = false, defaultValue = "10") Integer limit) {
        
        log.info("获取搜索历史请求");

        try {
            String userId = UserContext.getUserId();

            // 实现搜索历史逻辑
            List<String> result = getSearchHistoryForUser(userId, limit);

            return Result.success(result);
        } catch (Exception e) {
            log.error("获取搜索历史失败", e);
            return Result.fail("获取搜索历史失败: " + e.getMessage());
        }
    }

    @DeleteMapping("/history")
    @Operation(summary = "清空搜索历史", description = "清空当前用户的搜索历史")
    public Result<Boolean> clearSearchHistory() {
        log.info("清空搜索历史请求");

        try {
            String userId = UserContext.getUserId();

            // 实现清空搜索历史逻辑
            Boolean result = clearSearchHistoryForUser(userId);

            return Result.success(result);
        } catch (Exception e) {
            log.error("清空搜索历史失败", e);
            return Result.fail("清空搜索历史失败: " + e.getMessage());
        }
    }

    /**
     * 生成搜索建议
     */
    private List<String> generateSearchSuggestions(String input, String userId, Integer limit) {
        List<String> suggestions = new java.util.ArrayList<>();

        try {
            // 1. 基于输入的前缀匹配
            if (input.length() >= 2) {
                // 模拟从文档标题中提取建议
                suggestions.addAll(generateTitleSuggestions(input, limit / 2));

                // 模拟从标签中提取建议
                suggestions.addAll(generateTagSuggestions(input, limit / 2));
            }

            // 2. 限制返回数量
            if (suggestions.size() > limit) {
                suggestions = suggestions.subList(0, limit);
            }

        } catch (Exception e) {
            log.warn("生成搜索建议时发生错误: input={}, error={}", input, e.getMessage());
        }

        return suggestions;
    }

    /**
     * 生成标题建议
     */
    private List<String> generateTitleSuggestions(String input, Integer limit) {
        // 模拟标题建议
        List<String> titleSuggestions = new java.util.ArrayList<>();
        String[] commonTitles = {
            "用户手册", "技术文档", "产品说明", "操作指南", "开发文档",
            "API文档", "设计规范", "测试报告", "项目计划", "需求文档"
        };

        for (String title : commonTitles) {
            if (title.toLowerCase().contains(input.toLowerCase())) {
                titleSuggestions.add(title);
                if (titleSuggestions.size() >= limit) {
                    break;
                }
            }
        }

        return titleSuggestions;
    }

    /**
     * 生成标签建议
     */
    private List<String> generateTagSuggestions(String input, Integer limit) {
        // 模拟标签建议
        List<String> tagSuggestions = new java.util.ArrayList<>();
        String[] commonTags = {
            "重要", "紧急", "草稿", "已完成", "待审核",
            "公开", "私有", "共享", "归档", "最新"
        };

        for (String tag : commonTags) {
            if (tag.toLowerCase().contains(input.toLowerCase())) {
                tagSuggestions.add(tag);
                if (tagSuggestions.size() >= limit) {
                    break;
                }
            }
        }

        return tagSuggestions;
    }

    /**
     * 获取用户搜索历史
     */
    private List<String> getSearchHistoryForUser(String userId, Integer limit) {
        // 模拟搜索历史数据
        // 实际实现中应该从数据库或缓存中获取
        List<String> searchHistory = new java.util.ArrayList<>();

        // 模拟一些搜索历史
        searchHistory.add("用户手册");
        searchHistory.add("API文档");
        searchHistory.add("技术规范");
        searchHistory.add("操作指南");
        searchHistory.add("产品说明");

        // 限制返回数量
        if (searchHistory.size() > limit) {
            searchHistory = searchHistory.subList(0, limit);
        }

        return searchHistory;
    }

    /**
     * 清空用户搜索历史
     */
    private Boolean clearSearchHistoryForUser(String userId) {
        // 模拟清空搜索历史
        // 实际实现中应该删除数据库或缓存中的搜索历史记录
        log.info("清空用户搜索历史: userId={}", userId);
        return true;
    }
}
